namespace SmartSoft.Controls
{
    using SmartSoft.Controls.ChildGridControls;
    using System;
    using System.ComponentModel;
    using System.Data;
    using System.Runtime.CompilerServices;
    using System.Windows.Forms;

    [DefaultEvent("NewRowAdded")]
    public class GridDetail : GridControl
    {
        private int ii_FirstColumnIndex;

        public event EventHandler CellBottomLeftLeaved;

        public event EventHandler CellBottomRightLeaved;

        public event EventHandler CellRightLeaved;

        public event EventHandler CurrentRowsRemoved;

        public GridDetail()
        {
            base.AutoGenerateColumns = false;
            base.AllowUserToAddRows = false;
            base.AllowUserToDeleteRows = false;
        }

        private int GetNextColumn(int pi_CurrentColumn)
        {
            int lastVisibleColumn = this.LastVisibleColumn;
            foreach (DataGridViewColumn column in base.Columns)
            {
                if ((column.Visible && (column.Index > pi_CurrentColumn)) && (column.Index < lastVisibleColumn))
                {
                    lastVisibleColumn = column.Index;
                }
            }
            return lastVisibleColumn;
        }

        private int GetPreviousColumn(int pi_CurrentColumn)
        {
            int firstVisibleColumn = this.FirstVisibleColumn;
            foreach (DataGridViewColumn column in base.Columns)
            {
                if ((column.Visible && (column.Index < pi_CurrentColumn)) && (column.Index > firstVisibleColumn))
                {
                    firstVisibleColumn = column.Index;
                }
            }
            return firstVisibleColumn;
        }

        protected void OnCellBottomLeftLeaved(EventArgs e)
        {
            if (this.CellBottomLeftLeaved != null)
            {
                this.CellBottomLeftLeaved(this, e);
            }
        }

        protected void OnCellBottomRightLeaved(EventArgs e)
        {
            if (this.CellBottomRightLeaved != null)
            {
                this.CellBottomRightLeaved(this, e);
            }
        }

        protected void OnCellRightLeaved(EventArgs e)
        {
            if (this.CellRightLeaved != null)
            {
                this.CellRightLeaved(this, e);
            }
        }

        protected void OnCurrentRowsRemoved(EventArgs e)
        {
            if ((this.CurrentRowsRemoved != null) && (this.CurrentSelectionRows != null))
            {
                this.CurrentRowsRemoved(this, e);
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (this.FirstColumnIndex != -1)
            {
                if (keyData == Keys.Return)
                {
                    if (this.CheckBottomRightCell)
                    {
                        base.EndEdit();
                        this.OnCellRightLeaved(new EventArgs());
                        this.OnCellBottomRightLeaved(new EventArgs());
                        return true;
                    }
                    if (this.CheckBottomLeftCell)
                    {
                        this.OnCellBottomLeftLeaved(new EventArgs());
                        return true;
                    }
                    if (this.CheckRightCell)
                    {
                        this.OnCellRightLeaved(new EventArgs());
                        return true;
                    }
                }
                else if (keyData == Keys.F8)
                {
                    this.OnCurrentRowsRemoved(new EventArgs());
                }
                else if ((((keyData == Keys.Delete) && !base.CurrentCell.IsInEditMode) && (!base.CurrentCell.ReadOnly && (base.CurrentRow != null))) && (base.CurrentRow.DataBoundItem != null))
                {
                    DataRow row = ((DataRowView) base.CurrentRow.DataBoundItem).Row;
                    if ((row != null) && (base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName != null))
                    {
                        if ((((row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName].GetType().ToString() == "System.Decimal") || (row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName].GetType().ToString() == "System.Int")) || ((row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName].GetType().ToString() == "System.Int16") || (row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName].GetType().ToString() == "System.Int32"))) || ((row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName].GetType().ToString() == "System.Int64") || (row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName].GetType().ToString() == "System.Int16")))
                        {
                            row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName] = 0;
                            this.BeginEdit(false);
                        }
                        else if (row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName].GetType().ToString() == "System.String")
                        {
                            if (!(base.Columns[base.CurrentCell.ColumnIndex] is OptionColumn))
                            {
                                row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName] = "";
                                SendKeys.Send(" ");
                                SendKeys.Send("{BACKSPACE}");
                            }
                        }
                        else
                        {
                            row[base.Columns[base.CurrentCell.ColumnIndex].DataPropertyName] = SDBNull.Value;
                        }
                        row.EndEdit();
                    }
                }
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private bool CheckBottomLeftCell
        {
            get
            {
                if (((base.CurrentCell == null) || (base.CurrentCell.RowIndex < 0)) || (base.CurrentCell.ColumnIndex < 0))
                {
                    return false;
                }
                return ((base.CurrentCell.RowIndex == (base.Rows.Count - 1)) && (base.CurrentCell.ColumnIndex == this.FirstColumnIndex));
            }
        }

        private bool CheckBottomRightCell
        {
            get
            {
                if (((base.CurrentCell == null) || (base.CurrentCell.RowIndex < 0)) || (base.CurrentCell.ColumnIndex < 0))
                {
                    return false;
                }
                return ((base.CurrentCell.RowIndex == (base.Rows.Count - 1)) && (base.CurrentCell.ColumnIndex == this.LastVisibleColumn));
            }
        }

        private bool CheckRightCell
        {
            get
            {
                if (((base.CurrentCell == null) || (base.CurrentCell.RowIndex < 0)) || (base.CurrentCell.ColumnIndex < 0))
                {
                    return false;
                }
                return (base.CurrentCell.ColumnIndex == this.LastVisibleColumn);
            }
        }

        [Browsable(false)]
        public object CurrentSelectionRows
        {
            get
            {
                if (base.SelectedRows.Count > 0)
                {
                    return base.SelectedRows;
                }
                if ((((base.Rows.Count > 0) && (base.CurrentCell != null)) && ((base.CurrentCell.RowIndex >= 0) && (base.CurrentCell.ColumnIndex >= 0))) && !base.CurrentCell.IsInEditMode)
                {
                    return base.CurrentRow;
                }
                return null;
            }
        }

        [Description("The first column index that enter to fire a user's method."), DefaultValue(0)]
        public int FirstColumnIndex
        {
            get
            {
                return this.ii_FirstColumnIndex;
            }
            set
            {
                this.ii_FirstColumnIndex = value;
            }
        }

        private int FirstVisibleColumn
        {
            get
            {
                int lastVisibleColumn = this.LastVisibleColumn;
                foreach (DataGridViewColumn column in base.Columns)
                {
                    if (column.Visible && (column.Index < lastVisibleColumn))
                    {
                        lastVisibleColumn = column.Index;
                    }
                }
                return lastVisibleColumn;
            }
        }

        private int LastVisibleColumn
        {
            get
            {
                int index = 0;
                foreach (DataGridViewColumn column in base.Columns)
                {
                    if (column.Visible && (column.Index > index))
                    {
                        index = column.Index;
                    }
                }
                return index;
            }
        }

        public MoveNextType UserMoveNextCell
        {
            set
            {
                if (((base.Columns.Count >= 0) && (base.Rows.Count >= 0)) && (((base.CurrentCell != null) && (base.CurrentRow != null)) && (base.CurrentRow.DataBoundItem != null)))
                {
                    switch (value)
                    {
                        case MoveNextType.NoMovable:
                            return;

                        case MoveNextType.FirstCell:
                            base.CurrentCell = base[this.FirstVisibleColumn, base.CurrentCell.RowIndex];
                            return;

                        case MoveNextType.PreviousCell:
                            base.CurrentCell = base[this.GetPreviousColumn(base.CurrentCell.ColumnIndex), base.CurrentRow.Index];
                            return;

                        case MoveNextType.NextCell:
                            base.CurrentCell = base[this.GetNextColumn(base.CurrentCell.ColumnIndex), base.CurrentRow.Index];
                            return;

                        case MoveNextType.LastCell:
                            base.CurrentCell = base[this.LastVisibleColumn, base.CurrentRow.Index];
                            return;

                        case MoveNextType.FirstCellNextRow:
                            if (base.Rows.Count > (base.CurrentCell.RowIndex + 1))
                            {
                                base.CurrentCell = base[this.FirstColumnIndex, base.CurrentCell.RowIndex + 1];
                                return;
                            }
                            return;

                        case MoveNextType.LastCellPrevioucRow:
                            if (base.CurrentCell.RowIndex >= 1)
                            {
                                base.CurrentCell = base[this.LastVisibleColumn, base.CurrentCell.RowIndex - 1];
                                return;
                            }
                            return;

                        case MoveNextType.NextRow:
                            if (base.Rows.Count > (base.CurrentCell.RowIndex + 1))
                            {
                                base.CurrentCell = base[base.CurrentCell.ColumnIndex, base.CurrentCell.RowIndex + 1];
                                return;
                            }
                            return;

                        case MoveNextType.PreviousRow:
                            if (base.CurrentCell.RowIndex >= 1)
                            {
                                base.CurrentCell = base[base.CurrentCell.ColumnIndex, base.CurrentCell.RowIndex - 1];
                                return;
                            }
                            return;

                        case MoveNextType.DeleteCurrentRow:
                        {
                            DataRow row = ((DataRowView) base.CurrentRow.DataBoundItem).Row;
                            if (base.CurrentCell.RowIndex > 0)
                            {
                                base.CurrentCell = base[this.FirstVisibleColumn, base.CurrentCell.RowIndex - 1];
                            }
                            row.Delete();
                            return;
                        }
                    }
                }
            }
        }

        public enum MoveNextType
        {
            NoMovable,
            FirstCell,
            PreviousCell,
            NextCell,
            LastCell,
            FirstCellNextRow,
            LastCellPrevioucRow,
            NextRow,
            PreviousRow,
            DeleteCurrentRow
        }
    }
}

